import com.google.gson.Gson;
import org.dreamwork.misc.Base64;
import org.dreamwork.secure.AlgorithmMapping;
import org.dreamwork.secure.SecureContext;
import org.dreamwork.secure.SecureUtil;
import org.dreamwork.util.IOUtil;

import java.io.*;
import java.lang.ref.WeakReference;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: seth.yang
 * Date: 12-7-18
 * Time: 下午3:04
 */
public class Test {
    private static SecureContext context;

    static WeakHashMap whm = new WeakHashMap ();

    static class C {
        static ThreadLocal<C> pool = new ThreadLocal<C> ();

        private WeakHashMap<WeakReference<String>, Object> m = new WeakHashMap<WeakReference<String>, Object> ();

        private C () {
            pool.set (this);
        }

        public static C getC () {
            return pool.get ();
        }

        public void put (WeakReference<String> name, Object value) {
            m.put (name, value);
        }

        public<T> T get (WeakReference<String> name) {
            return (T) m.get (name);
        }
    }

    static class R {
        public WeakReference<String> key = new WeakReference<String> ("abc");

        private void m1 () {
            C c = new C ();
            c.put (key, "abc");
        }

        private void m2 () {
            C c = C.getC ();
            System.out.println (c.get (key));
        }
    }

    public static void main (String[] args) throws Exception {
        R r = new R ();
        r.m1 ();
        System.gc ();
/*
        for (int i = 0; i < 10; i ++) {
            Thread.sleep ((long) (Math.random () * 5000 + 1000));
*/
        r.m2 ();

        C c = C.getC ();
        r = null;
        System.gc ();
        System.out.println (c.m);
//        }
/*
        String a = new String("a");
        String b = new String("b");
        Map weakmap = new WeakHashMap ();
        Map map = new HashMap ();
        map.put(a, "aaa");
        map.put(b, "bbb");


        weakmap.put(a, "aaa");
        weakmap.put(b, "bbb");

        map.remove(a);

        a=null;
//        b=null;

        System.gc();
        Iterator i = map.entrySet().iterator();
        while (i.hasNext()) {
            Map.Entry en = (Map.Entry)i.next();
            System.out.println("map:"+en.getKey()+":"+en.getValue());
        }

        Iterator j = weakmap.entrySet().iterator();
        while (j.hasNext()) {
            Map.Entry en = (Map.Entry)j.next();
            System.out.println("weakmap:"+en.getKey()+":"+en.getValue());

        }
*/
    }

    private static void decrypt (Key kek) throws Exception {
        File dataFile = new File ("d:/tmp/data");
        byte[] data = IOUtil.read (dataFile);
        SecureUtil util = new SecureUtil (context);
        data = util.decrypt (data, kek);
        System.out.println (new String (data));
    }

    private static void encrypt (Key kek) throws Exception{
        SecureUtil util = new SecureUtil (context);
        byte[] data = util.encrypt ("This is a test".getBytes (), kek);
        FileOutputStream fos = new FileOutputStream ("d:/tmp/data");
        try {
            fos.write (data);
            fos.flush ();
        } finally {
            fos.close ();
        }
    }

    private static KeyFactory getRSAKeyFactory () throws NoSuchAlgorithmException {
        Provider provider = SecureUtil.getProvider ();
        return provider == null ?
                KeyFactory.getInstance ("RSA") : KeyFactory.getInstance ("RSA", provider);
    }

    private static PrivateKey getPrivateKey () throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
        File file = new File ("d:/tmp/keys/pkcs8_rsa_private_key.pem");
        FileReader fr = new FileReader (file);
        try {
            BufferedReader reader = new BufferedReader (fr);
            StringBuilder builder = new StringBuilder ();
            String line;

            while ((line = reader.readLine ()) != null) {
                if (!line.startsWith ("--"))
                    builder.append (line);
            }
            byte[] buff = builder.toString ().trim ().getBytes ("UTF-8");
            buff = Base64.decode (buff);


            KeyFactory factory = getRSAKeyFactory ();
            KeySpec spec = new PKCS8EncodedKeySpec (buff);
            return factory.generatePrivate (spec);
        } finally {
            fr.close ();
        }
    }

    public static PublicKey getPublicKey () throws InvalidKeySpecException, NoSuchAlgorithmException, IOException {
        File file = new File ("d:/tmp/keys/rsa_public_key.pem");
        FileReader fr = new FileReader (file);
        try {
            BufferedReader reader = new BufferedReader (fr);
            StringBuilder builder = new StringBuilder ();
            String line;

            while ((line = reader.readLine ()) != null) {
                if (!line.startsWith ("--"))
                    builder.append (line);
            }
            byte[] buff = builder.toString ().trim ().getBytes ("UTF-8");
            buff = Base64.decode (buff);

            KeyFactory factory = getRSAKeyFactory ();
            X509EncodedKeySpec spec = new X509EncodedKeySpec (buff);
            return factory.generatePublic (spec);
        } finally {
            fr.close ();
        }
    }

    static class TT {
        public static String KEY = "abc";
        static {
            System.out.println (System.getProperty (KEY));
        }

        static void doSomething () {
            System.out.println ("aaaaa  " + System.getProperty (KEY));
        }
    }
}